<!DOCTYPE html>
<html>
<head>
<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?d890b1f16fb364253e79c5bb20225c3a";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>


    

    

    
<!-- Baidu Tongji -->
<script>var _hmt = _hmt || []</script>
<script async src="//hm.baidu.com/hm.js?busuanzi_value_site_uv"></script>
<!-- End Baidu Tongji -->




    <meta charset="utf-8">
    <meta name="baidu-site-verification" content="FYMCShbUK8" />
    <meta name="baidu-site-verification" content="ZYRF7OxQRW" />
    <meta name="baidu-site-verification" content="cHSqtjI0PN" />
    <meta name="baidu-site-verification" content="cHSqtjI0PN" />
    <meta name="baidu-site-verification" content="cHSqtjI0PN" />
    
    
    <link rel="canonical" href="https://hhardyy.com/2019/04/06/了解React/">
    
    
    <title>读React源码 | 小方块 - hhardyy.com | 复杂的坑+归其原理+了解实现规则===解决？解决成功：加油解决成功;</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    
    <meta name="theme-color" content="#958e93">
    
    
    <meta name="keywords" content="react,jsx,diff">
    <meta name="description" content="我年轻需要指点">
<meta name="keywords" content="react,jsx,diff">
<meta property="og:type" content="article">
<meta property="og:title" content="读React源码">
<meta property="og:url" content="http://yoursite.com/2019/04/06/了解React/index.html">
<meta property="og:site_name" content="小方块 - hhardyy.com">
<meta property="og:description" content="我年轻需要指点">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://yoursite.com/images/konwReact/1ReactElement.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/2react中的Component和PualComponent.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/3react中的Component.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/4pureComponent.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/5react下的createRef.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/6createRefdo.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/7newcreateContext.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/8newcreateContext.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/9concurrentmodeJustSymbol.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/10suspenseYeshichangliangJPG.JPG">
<meta property="og:image" content="http://yoursite.com/images/konwReact/11lazyNotaSymbol.JPG">
<meta property="og:updated_time" content="2020-01-13T16:30:58.963Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="读React源码">
<meta name="twitter:description" content="我年轻需要指点">
<meta name="twitter:image" content="http://yoursite.com/images/konwReact/1ReactElement.JPG">
    
        <link rel="alternate" type="application/atom+xml" title="小方块 - hhardyy.com" href="/atom.xml">
    
    <link rel="shortcut icon" href="/hardyfavicon.ico">
    <link rel="stylesheet" href="//unpkg.com/hexo-theme-material-indigo@latest/css/style.css">
    <script>window.lazyScripts=[]</script>

    <!-- custom head -->
    

</head>

<body>
    <div id="loading" class="active"></div>

    <aside id="menu" class="hide" >
  <div class="inner flex-row-vertical">
    <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menu-off">
        <i class="icon icon-lg icon-close"></i>
    </a>
    <div class="brand-wrap" style="background-image:url(/img/paulGraham.jpg)">
      <div class="brand" style="background-color:#4154b2">
        <a href="/" class="avatar waves-effect waves-circle waves-light">
          <img src="/img/avatar.jpg">
        </a>
        <hgroup class="introduce">
          <h5 class="nickname">BingZhenhuang</h5>
          <a href="mailto:huangbingzhen@hhardyy.com" title="huangbingzhen@hhardyy.com" class="mail">huangbingzhen@hhardyy.com</a>
        </hgroup>
      </div>
    </div>
    <div class="scroll-wrap flex-col">
      <ul class="nav">
        
            <li class="waves-block waves-effect">
              <a href="/"  >
                <i class="icon icon-lg icon-home"></i>
                主页
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/archives"  >
                <i class="icon icon-lg icon-archives"></i>
                所有文章
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/tags"  >
                <i class="icon icon-lg icon-tags"></i>
                标签
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://github.com/HHardyy" target="_blank" >
                <i class="icon icon-lg icon-github"></i>
                Github
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://gitee.com/hhardyy" target="_blank" >
                <i class="icon icon-lg icon-cloud"></i>
                Gitee
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://juejin.im/user/59a26f926fb9a02487553b04"  >
                <i class="icon icon-lg icon-pencil"></i>
                掘金-圳
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://segmentfault.com/u/hhardyy"  >
                <i class="icon icon-lg icon-comments"></i>
                Segmentfault
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://codepen.io/HHardyy/" target="_blank" >
                <i class="icon icon-lg icon-codepen"></i>
                Codepen
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://www.freecodecamp.cn/hhardyy" target="_blank" >
                <i class="icon icon-lg icon-leaf"></i>
                Freecodecamp
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/友情链接"  >
                <i class="icon icon-lg icon-link"></i>
                友链
              </a>
            </li>
        
      </ul>
    </div>
  </div>
</aside>

    <main id="main">
        <header class="top-header" id="header">
    <div class="flex-row">
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light on" id="menu-toggle">
          <i class="icon icon-lg icon-navicon"></i>
        </a>
        <div class="flex-col header-title ellipsis">读React源码</div>
        
        <div class="search-wrap" id="search-wrap">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
                <i class="icon icon-lg icon-chevron-left"></i>
            </a>
            <input type="text" id="key" class="search-input" autocomplete="off" placeholder="输入感兴趣的关键字">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="search">
                <i class="icon icon-lg icon-search"></i>
            </a>
        </div>
        
        
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menuShare">
            <i class="icon icon-lg icon-share-alt"></i>
        </a>
        
    </div>
</header>
<header class="content-header post-header">

    <div class="container fade-scale">
        <h1 class="title">读React源码</h1>
        <h5 class="subtitle">
            
                <time datetime="2019-04-06T05:43:36.000Z" itemprop="datePublished" class="page-time">
  2019-04-06
</time>


            
        </h5>
    </div>

    


</header>


<div class="container body-wrap">
    
    <aside class="post-widget">
        <nav class="post-toc-wrap" id="post-toc">
            <h4>TOC</h4>
            <ol class="post-toc"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#1、JSX代码转变到javascript之createElement"><span class="post-toc-number">1.</span> <span class="post-toc-text">1、JSX代码转变到javascript之createElement</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#2、react-Element"><span class="post-toc-number">2.</span> <span class="post-toc-text">2、react-Element</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#3、react-Component"><span class="post-toc-number">3.</span> <span class="post-toc-text">3、react-Component</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#4、PureComponent"><span class="post-toc-number">4.</span> <span class="post-toc-text">4、PureComponent:</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#5、react-ref的三种方式"><span class="post-toc-number">5.</span> <span class="post-toc-text">5、react-ref的三种方式</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#1、string-ref"><span class="post-toc-number">5.1.</span> <span class="post-toc-text">1、string ref</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#2、function"><span class="post-toc-number">5.2.</span> <span class="post-toc-text">2、function</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#3、createRef"><span class="post-toc-number">5.3.</span> <span class="post-toc-text">3、createRef</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#6、forwardRef"><span class="post-toc-number">6.</span> <span class="post-toc-text">6、forwardRef</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#7、context"><span class="post-toc-number">7.</span> <span class="post-toc-text">7、context</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#8、ConCurrentMode（re16之后）"><span class="post-toc-number">8.</span> <span class="post-toc-text">8、ConCurrentMode（re16之后）</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#9、hooks"><span class="post-toc-number">9.</span> <span class="post-toc-text">9、hooks</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#react中的diff算法"><span class="post-toc-number">10.</span> <span class="post-toc-text">react中的diff算法</span></a></li></ol>
        </nav>
    </aside>
    
<article id="post-了解React"
  class="post-article article-type-post fade" itemprop="blogPost">

    <div class="post-card">
        <h1 class="post-card-title">读React源码</h1>
        <div class="post-meta">
            <time class="post-time" title="2019-04-06 13:43:36" datetime="2019-04-06T05:43:36.000Z"  itemprop="datePublished">2019-04-06</time>

            


            

        </div>
        <div class="post-content" id="post-content" itemprop="postContent">
            <p>我年轻需要指点</p>
<p><iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=543210521&auto=0&height=66"></iframe><br><a id="more"></a></p>
<p>首先得有源码<br>通过 CDN 获得 React 和 ReactDOM 的 UMD 版本。<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">crossorigin</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/react@16/umd/react.development.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">crossorigin</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/react-dom@16/umd/react-dom.development.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>上述版本仅用于开发环境，不适合用于生产环境。React 的压缩和优化之后的生产环境版本链接如下：<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">crossorigin</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/react@16/umd/react.production.min.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">crossorigin</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>如果需要加载指定版本的 react 和 react-dom，可以把 16 替换成需要加载的版本号。react16完全重写了核心代码，但是对于使用者来说是毫无感知的，不像vue和ng一样大版本更新的时候需要<br>调整兼容，react16还引入了fiber概念，从根本上解决js单线程运行当数据流量大动画卡帧的问题。  </p>
<h3 id="1、JSX代码转变到javascript之createElement"><a href="#1、JSX代码转变到javascript之createElement" class="headerlink" title="1、JSX代码转变到javascript之createElement"></a>1、JSX代码转变到javascript之createElement</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">React.createElement(<span class="string">'div'</span>,&#123;</div><div class="line">    class:'aaa',</div><div class="line">    data-name:<span class="string">'hardy'</span></div><div class="line">&#125;,<span class="string">"test"</span>)</div><div class="line"></div><div class="line">&lt;div <span class="class"><span class="keyword">class</span></span>=<span class="string">"aaa"</span> data-name=<span class="string">"hardy"</span>&gt;<span class="xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></div><div class="line"></div><div class="line"></div><div class="line">React.createElement(<span class="string">'div'</span>,&#123;</div><div class="line">    data-name=<span class="string">'hardy'</span>,</div><div class="line">    React.createElement(<span class="string">'span'</span>,<span class="literal">null</span>,<span class="string">'1'</span>),</div><div class="line">    React.createElement(<span class="string">'span'</span>,<span class="literal">null</span>,<span class="string">'2'</span>)</div><div class="line">&#125;,<span class="string">'hardy'</span>)</div><div class="line"></div><div class="line">&lt;div data-name=<span class="string">'hardy'</span>&gt;</div><div class="line">    &lt;span&gt;<span class="number">1</span>&lt;<span class="regexp">/span&gt;</span></div><div class="line"><span class="regexp">    &lt;span&gt;2&lt;/</span>span&gt;</div><div class="line">    hardy</div><div class="line">&lt;<span class="regexp">/div&gt;</span></div></pre></td></tr></table></figure>
<p>如果是组件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Hardy</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">a</span>&gt;</span>hardy<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></div><div class="line">&#125;</div><div class="line"></div><div class="line">&lt;Hardy id=<span class="string">'hardyid'</span>&gt;</div><div class="line">  &lt;span&gt;<span class="number">1</span>&lt;<span class="regexp">/span&gt;</span></div><div class="line"><span class="regexp">  &lt;span&gt;2&gt;&lt;/</span>span&gt;</div><div class="line">&lt;<span class="regexp">/Hardy&gt;</span></div></pre></td></tr></table></figure></p>
<p>那么createElement的第一项就不是字符串了，而是当成变量去传<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="meta">"use strict"</span>;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Hardy</span>(<span class="params"></span>) </span>&#123;</div><div class="line">  <span class="keyword">return</span> React.createElement(<span class="string">"a"</span>, <span class="literal">null</span>, <span class="string">"hardy"</span>);</div><div class="line">&#125;</div><div class="line"></div><div class="line">React.createElement(Hardy, &#123;</div><div class="line">  id: <span class="string">"hardyid"</span></div><div class="line">&#125;, React.createElement(<span class="string">"span"</span>, <span class="literal">null</span>, <span class="string">"1"</span>), React.createElement(<span class="string">"span"</span>, <span class="literal">null</span>, <span class="string">"2&gt;"</span>));</div></pre></td></tr></table></figure></p>
<p>如果自定义的这个组件叫hardy的话，它会被认为是原生dom里面的标签。在执行的时候就会报错，所以在声明自定义组件的时候，首字母一定要大写，这是一个规范.</p>
<h3 id="2、react-Element"><a href="#2、react-Element" class="headerlink" title="2、react-Element"></a>2、react-Element</h3><p>在react中createElement这个方法是这么实现的，它传入3个参数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">createElement</span>(<span class="params">type, config, children</span>) </span>&#123;</div><div class="line">  <span class="keyword">var</span> propName = <span class="keyword">void</span> <span class="number">0</span>;</div><div class="line"></div><div class="line">  <span class="comment">// Reserved names are extracted</span></div><div class="line">  <span class="keyword">var</span> props = &#123;&#125;;</div><div class="line"></div><div class="line">  <span class="keyword">var</span> key = <span class="literal">null</span>;</div><div class="line">  <span class="keyword">var</span> ref = <span class="literal">null</span>;</div><div class="line">  <span class="keyword">var</span> self = <span class="literal">null</span>;</div><div class="line">  <span class="keyword">var</span> source = <span class="literal">null</span>;</div><div class="line"></div><div class="line">  <span class="keyword">if</span> (config != <span class="literal">null</span>) &#123;</div><div class="line">    <span class="keyword">if</span> (hasValidRef(config)) &#123;</div><div class="line">      ref = config.ref;</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">if</span> (hasValidKey(config)) &#123;</div><div class="line">      key = <span class="string">''</span> + config.key;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    self = config.__self === <span class="literal">undefined</span> ? <span class="literal">null</span> : config.__self;</div><div class="line">    source = config.__source === <span class="literal">undefined</span> ? <span class="literal">null</span> : config.__source;</div><div class="line">    <span class="comment">// Remaining properties are added to a new props object</span></div><div class="line">    <span class="keyword">for</span> (propName <span class="keyword">in</span> config) &#123;</div><div class="line">      <span class="keyword">if</span> (hasOwnProperty$<span class="number">1.</span>call(config, propName) &amp;&amp; !RESERVED_PROPS.hasOwnProperty(propName)) &#123;</div><div class="line">        props[propName] = config[propName];</div><div class="line">      &#125;</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  <span class="comment">// Children can be more than one argument, and those are transferred onto</span></div><div class="line">  <span class="comment">// the newly allocated props object.</span></div><div class="line">  <span class="keyword">var</span> childrenLength = <span class="built_in">arguments</span>.length - <span class="number">2</span>;</div><div class="line">  <span class="keyword">if</span> (childrenLength === <span class="number">1</span>) &#123;</div><div class="line">    props.children = children;</div><div class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (childrenLength &gt; <span class="number">1</span>) &#123;</div><div class="line">    <span class="keyword">var</span> childArray = <span class="built_in">Array</span>(childrenLength);</div><div class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; childrenLength; i++) &#123;</div><div class="line">      childArray[i] = <span class="built_in">arguments</span>[i + <span class="number">2</span>];</div><div class="line">    &#125;</div><div class="line">    &#123;</div><div class="line">      <span class="keyword">if</span> (<span class="built_in">Object</span>.freeze) &#123;</div><div class="line">        <span class="built_in">Object</span>.freeze(childArray);</div><div class="line">      &#125;</div><div class="line">    &#125;</div><div class="line">    props.children = childArray;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  <span class="comment">// Resolve default props</span></div><div class="line">  <span class="keyword">if</span> (type &amp;&amp; type.defaultProps) &#123;</div><div class="line">    <span class="keyword">var</span> defaultProps = type.defaultProps;</div><div class="line">    <span class="keyword">for</span> (propName <span class="keyword">in</span> defaultProps) &#123;</div><div class="line">      <span class="keyword">if</span> (props[propName] === <span class="literal">undefined</span>) &#123;</div><div class="line">        props[propName] = defaultProps[propName];</div><div class="line">      &#125;</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">  &#123;</div><div class="line">    <span class="keyword">if</span> (key || ref) &#123;</div><div class="line">      <span class="keyword">var</span> displayName = <span class="keyword">typeof</span> type === <span class="string">'function'</span> ? type.displayName || type.name || <span class="string">'Unknown'</span> : type;</div><div class="line">      <span class="keyword">if</span> (key) &#123;</div><div class="line">        defineKeyPropWarningGetter(props, displayName);</div><div class="line">      &#125;</div><div class="line">      <span class="keyword">if</span> (ref) &#123;</div><div class="line">        defineRefPropWarningGetter(props, displayName);</div><div class="line">      &#125;</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">  <span class="keyword">return</span> ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>3个参数中的type，就是节点类型，如果是原生节点是字符串，如果是自定义组件就是class component 或者function component，或者react的组件Fragment、StricMode、Suspense,config是写在标签上的所有attr，它们都会变成keyvalue的形式存到config对象里面，我们需要从config里面筛选出props的内容或者href这种特殊的attr,children是标签中放的内容，可以是子标签或者文字,过程就是判断有没有合理的ref，有没有合理的key<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"> <span class="keyword">if</span> (hasValidRef(config)) &#123;</div><div class="line">    ref = config.ref;</div><div class="line">&#125;</div><div class="line"><span class="keyword">if</span> (hasValidKey(config)) &#123;</div><div class="line">    key = <span class="string">''</span> + config.key;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>然后就是对props进行处理，将不是内嵌的props另存到一个新的对象<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">for</span> (propName <span class="keyword">in</span> config) &#123;</div><div class="line">    <span class="keyword">if</span> (hasOwnProperty$<span class="number">1.</span>call(config, propName) &amp;&amp; !RESERVED_PROPS.hasOwnProperty(propName)) &#123;</div><div class="line">        props[propName] = config[propName];</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>内嵌的也就是RESERVED_PROPS中做了这样的声明<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> RESERVED_PROPS=&#123;</div><div class="line">   key:<span class="literal">true</span>,</div><div class="line">   ref:<span class="literal">true</span>,</div><div class="line">   __self:<span class="literal">true</span>,</div><div class="line">   __soure:<span class="literal">true</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>这里面的属性都不会出现在比如react项目中组件通信的时候的this.props中，然后是处理children<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> childrenLength = <span class="built_in">arguments</span>.length - <span class="number">2</span>;</div><div class="line">  <span class="keyword">if</span> (childrenLength === <span class="number">1</span>) &#123;</div><div class="line">    props.children = children;</div><div class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (childrenLength &gt; <span class="number">1</span>) &#123;</div><div class="line">    <span class="keyword">var</span> childArray = <span class="built_in">Array</span>(childrenLength);</div><div class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; childrenLength; i++) &#123;</div><div class="line">      childArray[i] = <span class="built_in">arguments</span>[i + <span class="number">2</span>];</div><div class="line">    &#125;</div><div class="line">    &#123;</div><div class="line">      <span class="keyword">if</span> (<span class="built_in">Object</span>.freeze) &#123;</div><div class="line">        <span class="built_in">Object</span>.freeze(childArray);</div><div class="line">      &#125;</div><div class="line">    &#125;</div><div class="line">    props.children = childArray;</div><div class="line">  &#125;</div></pre></td></tr></table></figure></p>
<p>children是可以有多个的，在一个节点上可能有很多兄弟节点，createElement(type, config, children),<br>默认是可以传入3个参数，但是实际上我们可以传入很多个，第三个参数之后的参数都认为是一个children,所以arguments.length-2就等于接下来的这些参数都是children，接着将这些children<br>存到新声明的数组childArray，最终它再放到props.children里面，通过this.props.children就可以拿到;接着是对默认props的处理，比如在写一个自己的组件的时候可以加上这么个值，这样<br>如果给别人用的时候，他没有传入这个值，就默认是设置的默认值。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">impoert React,&#123; Component &#125; <span class="keyword">from</span> <span class="string">'react'</span></div><div class="line">Hardy.defaultProps=&#123; <span class="attr">name</span>:hardy &#125;</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Hardy</span> <span class="keyword">extends</span> <span class="title">Component</span></span>&#123;</div><div class="line">&#125;</div><div class="line"><span class="keyword">if</span> (type &amp;&amp; type.defaultProps) &#123;   </div><div class="line">    <span class="keyword">var</span> defaultProps = type.defaultProps;</div><div class="line">    <span class="keyword">for</span> (propName <span class="keyword">in</span> defaultProps) &#123;</div><div class="line">      <span class="comment">//如果==就代表null和undefined都需要设置默认值，===就表示即使是null也不需要设置默认值</span></div><div class="line">      <span class="keyword">if</span> (props[propName] === <span class="literal">undefined</span>) &#123;    </div><div class="line">        props[propName] = defaultProps[propName];</div><div class="line">      &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>到这里的时候，预处理的内容已经完成了，然后它return了一个ReactElement，并传入上面处理的那些内容，return ReactElement(type, key, ref, self, source,<br>ReactCurrentOwner.current, props);ReactElement在第1881行的时候做了这样的声明<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/1ReactElement.JPG" alt="“like this”" title="">
                </div>
                <div class="image-caption">“like this”</div>
            </figure><br>ReactElement最终return一个这样的Object<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> element = &#123;</div><div class="line">    <span class="comment">// This tag allows us to uniquely identify this as a React Element</span></div><div class="line">    $$<span class="keyword">typeof</span>: REACT_ELEMENT_TYPE,   </div><div class="line"></div><div class="line">    <span class="comment">// Built-in properties that belong on the element</span></div><div class="line">    type: type,</div><div class="line">    key: key,</div><div class="line">    ref: ref,</div><div class="line">    props: props,</div><div class="line"></div><div class="line">    <span class="comment">// Record the component responsible for creating this element.</span></div><div class="line">    _owner: owner</div><div class="line">  &#125;;</div><div class="line">$$<span class="keyword">typeof</span>是REACT_ELEMENT_TYPE，用来标识Element是什么类型的，type是传进来的type，key是处理过的key，ref就是ref，props就是props，_owner就是_owner</div></pre></td></tr></table></figure></p>
<h3 id="3、react-Component"><a href="#3、react-Component" class="headerlink" title="3、react-Component"></a>3、react-Component</h3><p>Component就是组件<br>一般<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> React,&#123; Component &#125; <span class="keyword">from</span> <span class="string">'react</span></div><div class="line"><span class="string">class hardy extends Component&#123;&#125;</span></div></pre></td></tr></table></figure></p>
<p>或者<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> React <span class="keyword">from</span> <span class="string">'react'</span></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">hardy</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span></span>&#123;&#125;</div></pre></td></tr></table></figure></p>
<p>hardy都是去继承React的Component的base Class,其实React中有Component和PureComponent，两者唯一的区别就是PureComponent保证了组件在没有任何变化的情况下能够减少不必要的更新<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/2react中的Component和PualComponent.JPG" alt="“PureComponent”" title="">
                </div>
                <div class="image-caption">“PureComponent”</div>
            </figure><br>Component:<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/3react中的Component.JPG" alt="Component" title="">
                </div>
                <div class="image-caption">Component</div>
            </figure><br>Component被声明成了一个函数，接收3个参数props, context, updater，this.props和this.context是可以直接用的，emptyObject是我们获取的节点的实例然后挂载在this.refs上<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> emptyObject = &#123;&#125;;</div><div class="line">&#123;</div><div class="line">  <span class="built_in">Object</span>.freeze(emptyObject);</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>接下来第421行代码，Component的原型上挂载了一个setState，这是使用频率最多的api，它是用来更新组件状态的，partialState是要更新的新的state，可以是对象，也可以是个方法，callba<br>ck是更新完之后执行的方法，this.setState主要的部分是this.updater.enqueueSetState，也就是调用this.setState的时候初始化调用Component的时候传入的updater对象上面的enqueueS<br>etState方法，enqueueSetState在reactDom里面实现<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">Component.prototype.setState = <span class="function"><span class="keyword">function</span> (<span class="params">partialState, callback</span>) </span>&#123;</div><div class="line">  !(<span class="keyword">typeof</span> partialState === <span class="string">'object'</span> || <span class="keyword">typeof</span> partialState === <span class="string">'function'</span> || partialState == <span class="literal">null</span>) ? invariant(<span class="literal">false</span>, <span class="string">'setState(...): takes an object of state variables to update or a function which returns an object of state variables.'</span>) : <span class="keyword">void</span> <span class="number">0</span>;</div><div class="line">  <span class="keyword">this</span>.updater.enqueueSetState(<span class="keyword">this</span>, partialState, callback, <span class="string">'setState'</span>);</div><div class="line">&#125;;</div></pre></td></tr></table></figure></p>
<p>Component上面还有个方法叫forceUpdate，作用就是强制react的state更新<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">Component.prototype.forceUpdate = <span class="function"><span class="keyword">function</span> (<span class="params">callback</span>) </span>&#123;</div><div class="line">  <span class="keyword">this</span>.updater.enqueueForceUpdate(<span class="keyword">this</span>, callback, <span class="string">'forceUpdate'</span>);</div><div class="line">&#125;;</div></pre></td></tr></table></figure></p>
<p>Component的内容就是这些了，确实内容还是蛮少</p>
<h3 id="4、PureComponent"><a href="#4、PureComponent" class="headerlink" title="4、PureComponent:"></a>4、PureComponent:</h3><p>PureComponent继承自Component，区别就是加了isReactComponent=true,通过这个来标识继承自Component的是PureComponent<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/4pureComponent.JPG" alt="pureComponent" title="">
                </div>
                <div class="image-caption">pureComponent</div>
            </figure></p>
<h3 id="5、react-ref的三种方式"><a href="#5、react-ref的三种方式" class="headerlink" title="5、react-ref的三种方式"></a>5、react-ref的三种方式</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">constructor</span>()&#123;</div><div class="line">    <span class="keyword">super</span>()</div><div class="line">    <span class="keyword">this</span>.objRef=React.createRef()</div><div class="line">&#125;</div><div class="line">componentDitMount()&#123;</div><div class="line">    <span class="keyword">this</span>.refs.stringRef.textContent=<span class="string">"hardy string"</span>;     <span class="comment">//1</span></div><div class="line">    <span class="keyword">this</span>.methodsRef.textContent=<span class="string">"hardy function"</span>;       <span class="comment">//2</span></div><div class="line">    <span class="keyword">this</span>.objRef.current.textContent=<span class="string">"hardy createRef"</span>   <span class="comment">//3</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h4 id="1、string-ref"><a href="#1、string-ref" class="headerlink" title="1、string ref"></a>1、string ref</h4><p>想要获取节点的元素的props上添加一个ref属性，然后传入字符串，然后在完成这个节点的渲染之后在this.refs上面挂载这个属性的key，如果是节点就是节点，如果是组件就是组件，对应的就是<br>这个节点的实例的对象（将要被废弃的使用方式）</p>
<p></p><p ref="stringRef"></p><p></p>
<h4 id="2、function"><a href="#2、function" class="headerlink" title="2、function"></a>2、function</h4><p>ref传入一个方法，方法接收一个参数，参数就是当前的实例，如果是节点就是节点，如果是组件就是组件</p>
<p></p><p ref="{ele=">(this.methodsRef=ele)}&gt;</p><p></p>
<h4 id="3、createRef"><a href="#3、createRef" class="headerlink" title="3、createRef"></a>3、createRef</h4><p>这个是react提供的api,利用this.objRef=React.createRef()创建了一个null的current对象，然后传给某个节点，传完之后在组件渲染完成之后，将对应的节点挂载到current上</p>
<p></p><p ref="{this.objRef}"></p><br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/5react下的createRef.JPG" alt="createRef" title="">
                </div>
                <div class="image-caption">createRef</div>
            </figure><br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/6createRefdo.JPG" alt="createRefdo" title="">
                </div>
                <div class="image-caption">createRefdo</div>
            </figure><br>Object.seal()方法封闭一个对象，阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要可写就可以改变。<p></p>
<h3 id="6、forwardRef"><a href="#6、forwardRef" class="headerlink" title="6、forwardRef"></a>6、forwardRef</h3><p>之前从上层组件传到子组件的方式只有props，forwardRef可以传入第二个参数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> Childcom=React.forwardRef(<span class="function">(<span class="params">props,ref</span>)=&gt;</span>&#123;</div><div class="line">    &lt;input type=<span class="string">"text"</span> ref=&#123;ref&#125;&gt;</div><div class="line">&#125;)</div><div class="line"><span class="keyword">export</span> <span class="keyword">default</span> Com extends React.Component&#123;</div><div class="line">    <span class="keyword">constructor</span>()&#123;</div><div class="line">        <span class="keyword">super</span>()</div><div class="line">        <span class="keyword">this</span>.creaRef=React.createRef()</div><div class="line">    &#125;</div><div class="line">    componentDidMount()&#123;</div><div class="line">        <span class="keyword">this</span>.ref.current.value=<span class="string">"hardy forwardRef"</span></div><div class="line">    &#125;</div><div class="line">    render()&#123;</div><div class="line">        <span class="keyword">return</span> (</div><div class="line">            &lt;Childcom ref=&#123;<span class="keyword">this</span>.ref&#125;&gt;<span class="xml"><span class="tag">&lt;/<span class="name">Childcom</span>&gt;</span></span></div><div class="line">        )</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>在react中forwardRef的实现<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">forwardRef</span>(<span class="params">render</span>) </span>&#123;</div><div class="line">  &#123;</div><div class="line">    <span class="keyword">if</span> (render != <span class="literal">null</span> &amp;&amp; render.$$<span class="keyword">typeof</span> === REACT_MEMO_TYPE) &#123;</div><div class="line">      warningWithoutStack$<span class="number">1</span>(<span class="literal">false</span>, <span class="string">'forwardRef requires a render function but received a `memo` '</span> + <span class="string">'component. Instead of forwardRef(memo(...)), use '</span> + <span class="string">'memo(forwardRef(...)).'</span>);</div><div class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">typeof</span> render !== <span class="string">'function'</span>) &#123;</div><div class="line">      warningWithoutStack$<span class="number">1</span>(<span class="literal">false</span>, <span class="string">'forwardRef requires a render function but was given %s.'</span>, render === <span class="literal">null</span> ? <span class="string">'null'</span> : <span class="keyword">typeof</span> render);</div><div class="line">    &#125; <span class="keyword">else</span> &#123;</div><div class="line">      !(</div><div class="line">      <span class="comment">// Do not warn for 0 arguments because it could be due to usage of the 'arguments' object</span></div><div class="line">      render.length === <span class="number">0</span> || render.length === <span class="number">2</span>) ? warningWithoutStack$<span class="number">1</span>(<span class="literal">false</span>, <span class="string">'forwardRef render functions accept exactly two parameters: props and ref. %s'</span>, render.length === <span class="number">1</span> ? <span class="string">'Did you forget to use the ref parameter?'</span> : <span class="string">'Any additional parameter will be undefined.'</span>) : <span class="keyword">void</span> <span class="number">0</span>;</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">if</span> (render != <span class="literal">null</span>) &#123;</div><div class="line">      !(render.defaultProps == <span class="literal">null</span> &amp;&amp; render.propTypes == <span class="literal">null</span>) ? warningWithoutStack$<span class="number">1</span>(<span class="literal">false</span>, <span class="string">'forwardRef render functions do not support propTypes or defaultProps. '</span> + <span class="string">'Did you accidentally pass a React component?'</span>) : <span class="keyword">void</span> <span class="number">0</span>;</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  <span class="keyword">return</span> &#123;</div><div class="line">    $$<span class="keyword">typeof</span>: REACT_FORWARD_REF_TYPE,</div><div class="line">    render: render</div><div class="line">  &#125;;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<h3 id="7、context"><a href="#7、context" class="headerlink" title="7、context"></a>7、context</h3><p>react中组件组件通信用props,多层组件通信的时候中间隔着不同的组件，这时候用context，父组件设置了一个context，其所有的子组件都可以通过context访问到<br>context的实现方式有两种<br>1、childContextTypes（即将被废弃）<br>2、createContext（re16提供的）<br>关系<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">export</span> <span class="keyword">default</span> ()=&gt;&#123;</div><div class="line">    &lt;Parent&gt;</div><div class="line">        &lt;Child/&gt;</div><div class="line">        &lt;Child/&gt;</div><div class="line">    &lt;<span class="regexp">/Parent&gt;</span></div><div class="line"><span class="regexp">&#125;</span></div></pre></td></tr></table></figure></p>
<p>父组件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Parent</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span></span>&#123;</div><div class="line">    <span class="keyword">constructor</span>()&#123;</div><div class="line">       <span class="keyword">super</span>()</div><div class="line">       <span class="keyword">this</span>.state=&#123;</div><div class="line">           ChildContext:<span class="string">"hardy"</span></div><div class="line">       &#125;</div><div class="line">    &#125;</div><div class="line">    getChildContext()&#123;</div><div class="line">        <span class="keyword">return</span> &#123;<span class="attr">value</span>:<span class="keyword">this</span>.state.ChildContext&#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line">Parent.childContextTypes=&#123;</div><div class="line">    value:PropTypes.string   <span class="comment">//和PropTypes一样，如果不声明是无法获取到的，</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>子组件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">Child.contextTypes=&#123;</div><div class="line">    value:PropTypes.string</div><div class="line">&#125;</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Child</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span></span>&#123;</div><div class="line">    render()&#123;</div><div class="line">        <span class="keyword">return</span> (<span class="xml"><span class="tag">&lt;<span class="name">p</span>&gt;</span>&#123;this.context.value&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span>)</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>上面那是老的context用法 ，接下来是新的api<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> &#123; Provider,Consumer &#125; =React.createContext(<span class="string">'default'</span>)</div></pre></td></tr></table></figure></p>
<p>Provider和Consumer分别是context的提供方和订阅方,在Parent直接<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;Provider value=&#123;<span class="keyword">this</span>.state.newContext&#125;&gt;<span class="xml"><span class="tag">&lt;/<span class="name">Provider</span>&gt;</span></span></div></pre></td></tr></table></figure></p>
<p>然后在Child这边需要用到的地方直接,Consumer,在父组件定义了context之后，子组件的哪个地方需要用到这个context就可以直接用这个组件就可以了<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;Consumer&gt;&#123;value=&gt;<span class="xml"><span class="tag">&lt;<span class="name">p</span>&gt;</span>newContext:&#123;value&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span>&#125;&lt;<span class="regexp">/Consumer&gt;</span></div></pre></td></tr></table></figure></p>
<figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/7newcreateContext.JPG" alt="newcreateContext" title="">
                </div>
                <div class="image-caption">newcreateContext</div>
            </figure>
<p>createContext接收两个参数，一个是defaultValue，另一个calculateChangedBits用来计算新老API变化的，<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/8newcreateContext.JPG" alt="newcreateContext" title="">
                </div>
                <div class="image-caption">newcreateContext</div>
            </figure><br>_currentValue: defaultValue,_currentValue2: defaultValue是用来更新最新的defaultValue值</p>
<h3 id="8、ConCurrentMode（re16之后）"><a href="#8、ConCurrentMode（re16之后）" class="headerlink" title="8、ConCurrentMode（re16之后）"></a>8、ConCurrentMode（re16之后）</h3><p>ConCurrentMode（本叫assignMode）16.6之后名字更新，作用是让react的渲染过程进行优先的排比，并且能让整体的渲染过程中断，它可以进行任务调度，把更多的cpu性能（javascript是单线<br>程语言，如果react的某个更新渲染占用了非常长的进程，会导致动画卡顿或者其他的一些响应变卡，因为这时候js正在运行react的更新，这时候react可以有选择的优先进行优先级更高的任务，比<br>如一个人在游泳，他一次要游到水底再上来，如果他中间岸上有人有更重要的事情找他，但是只能等他先游上来才能继续，但是这个就提供了每隔一段时间会看一下是否有更重要的事情然后先做。）<br>ConCurrentMode有个特性，在ConCurrentMode子树中渲染了ConCurrentMode之后，它下面所有节点的更新就是低优先级的更新<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/9concurrentmodeJustSymbol.JPG" alt="concurrentmodeJustSymbol" title="">
                </div>
                <div class="image-caption">concurrentmodeJustSymbol</div>
            </figure><br>react16.6已经可以使用一部分功能的新的react filter<br>Suspense：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">SuspenseComp</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">const</span> data=requestData()</div><div class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">p</span>&gt;</span>&#123;data&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></div><div class="line">&#125;</div><div class="line"><span class="keyword">export</span> <span class="keyword">default</span> ()=&gt;&#123;</div><div class="line">   &lt;Suspense fallback=<span class="string">"loading"</span>&gt;  </div><div class="line">       &lt;SuspenseComp/&gt;    <span class="comment">//SuspenseComp中的data还没有的时候显示loading</span></div><div class="line">   &lt;<span class="regexp">/Suspense&gt;</span></div><div class="line"><span class="regexp">&#125;</span></div></pre></td></tr></table></figure></p>
<p>这个api目前在正式的项目不建议用，可以先用lazy(lazy.js)<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> React <span class="keyword">from</span> <span class="string">'react'</span></div><div class="line"><span class="keyword">export</span> <span class="keyword">default</span> ()=&gt; <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">p</span>&gt;</span>lazy comp<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></div><div class="line"></div><div class="line"><span class="keyword">import</span> React,&#123; lazy &#125; <span class="keyword">from</span> <span class="string">'react'</span></div><div class="line"><span class="keyword">const</span> lazyComp=lazy(<span class="function"><span class="params">()</span>=&gt;</span>&#123;<span class="keyword">import</span>(./lazy.js)&#125;)</div></pre></td></tr></table></figure></p>
<p>这个就是用了webpack的异步加载的api,看源码之后发现Suspense也是个symbol<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/10suspenseYeshichangliangJPG.JPG" alt="suspenseYeshichangliang" title="">
                </div>
                <div class="image-caption">suspenseYeshichangliang</div>
            </figure><br>lazy函数接收一个方法，ctor<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/konwReact/11lazyNotaSymbol.JPG" alt="lazyNotaSymbol" title="">
                </div>
                <div class="image-caption">lazyNotaSymbol</div>
            </figure><br>_status用来记录状态<br>_result用来记录promise对象返回之后的属性，最终resolve出来的会放在_result上面</p>
<h3 id="9、hooks"><a href="#9、hooks" class="headerlink" title="9、hooks"></a>9、hooks</h3><p>要安装hooks必须要react&amp;&amp;react-dom16.7以上，如果没有16.7.0，可以安装react16.7.0-alpha.2&amp;&amp;react-dom16.7.0-alpha.2，如果已经有了直接安装最新版<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> React,&#123; useState &#125; <span class="keyword">from</span> <span class="string">'react'</span></div><div class="line"><span class="keyword">export</span> <span class="keyword">default</span> ()=&gt;&#123;</div><div class="line">	<span class="keyword">const</span> [name,setname]=useState(<span class="string">'hardy'</span>)</div><div class="line">	<span class="keyword">return</span> (</div><div class="line">	&lt;&gt;</div><div class="line">	   &lt;p&gt;my name is:&#123;name&#125;&lt;<span class="regexp">/p&gt;</span></div><div class="line"><span class="regexp">		 &lt;input type="text" value=&#123;name&#125; onChange=&#123;e=&gt;setName(e.target.value)&#125;&gt;&lt;/i</span>nput&gt;</div><div class="line">	&lt;<span class="regexp">/&gt;</span></div><div class="line"><span class="regexp">	)</span></div><div class="line"><span class="regexp">&#125;</span></div></pre></td></tr></table></figure></p>
<p>这是一个函数组件，和class组件的区别就是没有this对象，没有this就没有this.state,也没有生命周期方法，这个demo用hooks来给组件存储state，给useState传入一个默认值，然后返回一个<br>数组，再解构。name是变量，setname是改变变量的方法.</p>
<h3 id="react中的diff算法"><a href="#react中的diff算法" class="headerlink" title="react中的diff算法"></a>react中的diff算法</h3><p>虚拟dom中的diff算法<br>1、state<br>2、jsx模板<br>3、数据+模板  生成虚拟dom（虚拟dom就是一个js对象，用它来描述真实dom）（损耗了性能）<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[<span class="string">'div'</span>,&#123;<span class="attr">id</span>:<span class="string">'abc'</span>&#125;,[<span class="string">'span'</span>,&#123;&#125;,<span class="string">'helloword'</span>]]</div></pre></td></tr></table></figure></p>
<p>4、用虚拟dom的结构生成真实的dom，来显示<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;div id=<span class="string">'abc'</span>&gt;<span class="xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span>hello word<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><span class="xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></div></pre></td></tr></table></figure></p>
<p>5、state 发生变化<br>6、数据+模板  生成新的虚拟dom （提升性能）<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[<span class="string">'div'</span>,&#123;<span class="attr">id</span>:<span class="string">'abc'</span>&#125;,[<span class="string">'span'</span>,&#123;&#125;,<span class="string">'bye bye'</span>]]</div></pre></td></tr></table></figure></p>
<p>7、比较原始虚拟dom和新的虚拟dom的区别，找到区别是span中的内容（提升性能）<br>8、直接操作dom，改变span中的内容<br>优点：<br>性能提升<br>使得跨端应用得以实现（比如react native）</p>
<p>待续….</p>

        </div>

        <blockquote class="post-copyright">
    <div class="content">
        
<span class="post-time">
    最后更新时间：<time datetime="2020-01-13T16:30:58.963Z" itemprop="dateUpdated">2020-01-14 00:30:58</time>
</span><br>


        
        谢谢浏览，我会继续努力的，示例：<a href="/2019/04/06/了解React/" target="_blank" rel="external">http://yoursite.com/2019/04/06/了解React/</a>
        
    </div>
    <footer>
        <a href="http://yoursite.com">
            <img src="/img/avatar.jpg" alt="BingZhenhuang">
            BingZhenhuang
        </a>
    </footer>
</blockquote>

        
<div class="page-reward">
    <a id="rewardBtn" href="javascript:;" class="page-reward-btn waves-effect waves-circle waves-light">赏</a>
</div>



        <div class="post-footer">
            
	<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/diff/">diff</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/jsx/">jsx</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/react/">react</a></li></ul>


            
<div class="page-share-wrap">
    

<div class="page-share" id="pageShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://yoursite.com/2019/04/06/了解React/&title=《读React源码》 — 小方块 - hhardyy.com&pic=http://yoursite.com/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://yoursite.com/2019/04/06/了解React/&title=《读React源码》 — 小方块 - hhardyy.com&source=我年轻需要指点
" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://yoursite.com/2019/04/06/了解React/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《读React源码》 — 小方块 - hhardyy.com&url=http://yoursite.com/2019/04/06/了解React/&via=http://yoursite.com" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://yoursite.com/2019/04/06/了解React/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>



    <a href="javascript:;" id="shareFab" class="page-share-fab waves-effect waves-circle">
        <i class="icon icon-share-alt icon-lg"></i>
    </a>
</div>



        </div>
    </div>

    
<nav class="post-nav flex-row flex-justify-between">
  
    <div class="waves-block waves-effect prev">
      <a href="/2019/06/15/根据经纬度计算两点间距/" id="post-prev" class="post-nav-link">
        <div class="tips"><i class="icon icon-angle-left icon-lg icon-pr"></i> Prev</div>
        <h4 class="title">根据经纬度计算两点间距</h4>
      </a>
    </div>
  

  
    <div class="waves-block waves-effect next">
      <a href="/2019/02/21/bind、call、apply/" id="post-next" class="post-nav-link">
        <div class="tips">Next <i class="icon icon-angle-right icon-lg icon-pl"></i></div>
        <h4 class="title">bind、call、apply</h4>
      </a>
    </div>
  
</nav>



    














</article>

<div id="reward" class="page-modal reward-lay">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <h3 class="reward-title">
        <i class="icon icon-quote-left"></i>
        🤠 请我喝可乐！
        <i class="icon icon-quote-right"></i>
    </h3>
    <div class="reward-content" style="width:50%">
        
        <div class="reward-code" style="text-align:center">
            <div style="width:300px;margin:0px auto;">
               <img id="rewardCode" style="width:50%;height:60%;display:block; margin:0px auto;" src="/img/alipay.jpg" alt="支付宝打赏二维码">
               <span style="display:inline-block; margin-bottom:20px;">0.88(支付宝 aliPay)</span>
               <img id="rewardCode" style="width:50%;height:60%;display:block; margin:0px auto;" src="/img/wechat.jpg" alt="微信打赏二维码">
               <span style="display:inline-block;">0.88(微信 weChat)</span>
            </div>
        </div>
    </div>
</div>



</div>

        <script>
!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e<d.length;e++)d[e].alpha<=0?(t.body.removeChild(d[e].el),d.splice(e,1)):(d[e].y--,d[e].scale+=.004,d[e].alpha-=.013,d[e].el.style.cssText="left:"+d[e].x+"px;top:"+d[e].y+"px;opacity:"+d[e].alpha+";transform:scale("+d[e].scale+","+d[e].scale+") rotate(45deg);background:"+d[e].color+";z-index:99999");requestAnimationFrame(r)}function o(){var t="function"==typeof e.onclick&&e.onclick;e.onclick=function(e){t&&t(),i(e)}}function i(e){var a=t.createElement("div");a.className="heart",d.push({el:a,x:e.clientX-5,y:e.clientY-5,scale:1,alpha:1,color:s()}),t.body.appendChild(a)}function c(e){var a=t.createElement("style");a.type="text/css";try{a.appendChild(t.createTextNode(e))}catch(t){a.styleSheet.cssText=e}t.getElementsByTagName("head")[0].appendChild(a)}function s(){return"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}var d=[];e.requestAnimationFrame=function(){return e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)}}(),n()}(window,document);
</script>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<script>
    function secondToDate(second) {
        if (!second) {
            return 0;
        }
        var time = new Array(0, 0, 0, 0, 0);
        if (second >= 365 * 24 * 3600) {
            time[0] = parseInt(second / (365 * 24 * 3600));
            second %= 365 * 24 * 3600;
        }
        if (second >= 24 * 3600) {
            time[1] = parseInt(second / (24 * 3600));
            second %= 24 * 3600;
        }
        if (second >= 3600) {
            time[2] = parseInt(second / 3600);
            second %= 3600;
        }
        if (second >= 60) {
            time[3] = parseInt(second / 60);
            second %= 60;
        }
        if (second > 0) {
            time[4] = second;
        }
        return time;
    }</script>
<script type="text/javascript" language="javascript">
    function setTime() {
        var create_time = Math.round(new Date(Date.UTC(2017, 08, 18, 11, 42, 23)).getTime() / 1000);
        var timestamp = Math.round((new Date().getTime() + 8 * 60 * 60 * 1000) / 1000);
        currentTime = secondToDate((timestamp - create_time));
        currentTimeHtml = 'Running：' + currentTime[0] + '年 ' + currentTime[1] + '天 '
                + currentTime[2] + '时 ' + currentTime[3] + '分 ' + currentTime[4]
                + '秒';
        document.getElementById("htmer_time").innerHTML = currentTimeHtml;
    }    setInterval(setTime, 1000);
</script>
<footer class="footer">
    <div class="top">
        

        <p>
          <span id="busuanzi_container_page_pv">
             [&nbsp;浏览量：&nbsp;<span id="busuanzi_value_page_pv"></span>&nbsp;]
          </span>
        </p>
    </div>
    <div class="bottom">
        <p>
        <span>BingZhenhuang &copy; 2017 - 2020</span>
            <span>
                
                Power by <a href="https://hhardyy.github.io/" target="_blank">zhen On August 8</a> 
            </span>
            <span id="htmer_time" "></span>
        </p>
    </div>
</footer>

    </main>
    <div class="mask" id="mask"></div>
<a href="javascript:;" id="gotop" class="waves-effect waves-circle waves-light"><span class="icon icon-lg icon-chevron-up"></span></a>



<div class="global-share" id="globalShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://yoursite.com/2019/04/06/了解React/&title=《读React源码》 — 小方块 - hhardyy.com&pic=http://yoursite.com/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://yoursite.com/2019/04/06/了解React/&title=《读React源码》 — 小方块 - hhardyy.com&source=我年轻需要指点
" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://yoursite.com/2019/04/06/了解React/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《读React源码》 — 小方块 - hhardyy.com&url=http://yoursite.com/2019/04/06/了解React/&via=http://yoursite.com" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://yoursite.com/2019/04/06/了解React/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>


<div class="page-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <p>扫一扫，分享到微信</p>
    <img src="" alt="微信分享二维码">
</div>




    <script src="//cdn.bootcss.com/node-waves/0.7.4/waves.min.js"></script>
<script>
var BLOG = { ROOT: '/', SHARE: true, REWARD: true };


</script>

<script src="//unpkg.com/hexo-theme-material-indigo@latest/js/main.min.js"></script>


<div class="search-panel" id="search-panel">
    <ul class="search-result" id="search-result"></ul>
</div>
<template id="search-tpl">
<li class="item">
    <a href="{path}" class="waves-block waves-effect">
        <div class="title ellipsis" title="{title}">{title}</div>
        <div class="flex-row flex-middle">
            <div class="tags ellipsis">
                {tags}
            </div>
            <time class="flex-col time">{date}</time>
        </div>
    </a>
</li>
</template>

<script src="//unpkg.com/hexo-theme-material-indigo@latest/js/search.min.js" async></script>








<script>
(function() {
    var OriginTitile = document.title, titleTime;
    document.addEventListener('visibilitychange', function() {
        if (document.hidden) {
            document.title = '(•‾̑⌣‾̑•)✧˖°回来看我';
            clearTimeout(titleTime);
        } else {
            document.title = '(゜-゜)つロ欢迎回来';
            titleTime = setTimeout(function() {
                document.title = OriginTitile;
            },2000);
        }
    });
})();
</script>



</body>
</html>
